package game;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.util.glu.GLU.*;

import java.io.File;
import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;

public class Game implements Runnable {
	private boolean run = true;
	private final int width = 800, height = 600;
	private World world;
	private long lastFrame, lastFPS;
	private int frames, currentFPS;
	private String title = "A Game";
	private float fov = 45.0f;
	private boolean limitFPS = true;
	public boolean wireframe = false;

	public void run() {
		try {
			Display.setDisplayMode(new DisplayMode(width, height));
			Display.setTitle(title);
			Display.create();
		} catch (LWJGLException e) {
			System.out.println("Failed to create diplay");
			if (Display.isCreated()) {
				Display.destroy();
			}
			System.exit(1);
		}

		initGL();
		Graphics.init();
		world = new World(this);
		Mouse.setGrabbed(true);

		getDelta();
		lastFPS = getTime();

		while (run) {
			if (Display.isCloseRequested()) {
				stop();
			}
			
			int delta = getDelta();
			
			update(delta);
			render();
			Display.update();
			
			if (limitFPS) {
				Display.sync(80);
			}
			Display.setTitle(title + " | FPS: " + currentFPS);
		}
	}

	private void update(int delta) {
		world.update(delta);

		if (getTime() - lastFPS > 1000) {
			currentFPS = frames;
			frames = 0;
			lastFPS += 1000;
		}
		frames++;
	}

	private void render() {
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		if (wireframe) {
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		} else {
			glPolygonMode(GL_FRONT, GL_FILL);
		}
		world.render();
	}

	private void initGL() {
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(fov, width / height, 0.1f, 1000.0f);
		glMatrixMode(GL_MODELVIEW);

		glEnable(GL_DEPTH_TEST);
		
		glEnable(GL_LIGHT0);
		
		IntBuffer lights = BufferUtils.createIntBuffer(16);
        glGetInteger(GL_MAX_LIGHTS, lights);
        System.out.println("Max light sources: " + lights.get(0));
	}

	private void stop() {
		Display.destroy();
		System.exit(0);
	}

	public int getDelta() {
		long time = getTime();
		int delta = (int) (time - lastFrame);
		lastFrame = time;

		return delta;
	}

	private long getTime() {
		return (Sys.getTime() * 1000) / Sys.getTimerResolution();
	}

	public static void main(String[] args) {
		System.setProperty("org.lwjgl.librarypath", new File("lib/native").getAbsolutePath());
		new Thread(new Game()).run();
	}
}
